#==================================================================
#
#  This file is part of the PRIMEGENS project.
#
#==================================================================

#==================================================================
#
#  This file includes code from PRIMER3, cited below:
#
# Steve Rozen and Helen J. Skaletsky (2000) Primer3 on the WWW for
# general users and for biologist programmers. In: Krawetz S, Misener S
# (eds) Bioinformatics Methods and Protocols: Methods in Molecular
# Biology. Humana Press, Totowa, NJ, pp 365-386.  Source code available
# from https://sourceforge.net/projects/primer3/
#
#  In particular, most lines dealing with primer3 files (files 
#  names start with a p3_ prefix) were almost directly lifted 
#  from primer3's makefile
# ======================================================================


# For VALGRIND -- see end of this makefile for testing primer3_core
# with valgrind, a leak and memory access checker.
TESTOPTS= 
WINMAKE			=mingw32-make

LDLIBS     		= -lm
AR         		= ar
CPP        		= g++
CC			= gcc  
CC_OPTS			= -g #-D__USE_FIXED_PROTOTYPES__
O_OPTS			= -O2
P_DEFINES		=
CC_FLAGS	 	= $(CC_OPTS) $(O_OPTS)
LDFLAGS 		= -g

#PRIMER3 Start

# ======================================================================
# If you have trouble with library skew when moving primer3 executables
# between systems, you might want to set LIBOPTS to -static
LIBOPTS =

ifeq ($(TESTOPTS),--windows)
	PRIMER_EXE      = p3_primer3_core.exe
	NTDPAL_EXE	= p3_ntdpal.exe
	NTTHAL_EXE	= p3_ntthal.exe
	OLIGOTM_EXE	= p3_oligotm.exe
	LONG_SEQ_EXE	= p3_long_seq_tm_test.exe
else
	PRIMER_EXE  = ../primer3/p3_primer3_core
	NTDPAL_EXE	= ../primer3/p3_ntdpal
	NTTHAL_EXE	= ../primer3/p3_ntthal
	OLIGOTM_EXE	= ../primer3/p3_oligotm
	LONG_SEQ_EXE	= ../primer3/p3_long_seq_tm_test
endif
LIBOLIGOTM      = p3_liboligotm.a
LIBOLIGOTM_DYN  = p3_liboligotm.so.1.2.0
LIBDPAL         = p3_libdpal.a
LIBDPAL_DYN     = p3_libdpal.a.so.1.0.0
LIBTHAL         = p3_libthal.a
LIBTHAL_DYN     = p3_libthal.a.so.1.0.0
LIBPRIMER3      = p3_libprimer3.a
LIBPRIMER3_DYN  = p3_libprimer3.so.1.0.0
LIBRARIES       = $(LIBPRIMER3) $(LIBDPAL) $(LIBTHAL) $(LIBOLIGOTM) 
DYNLIBS         = $(LIBPRIMER3_DYN) $(LIBDPAL_DYN) $(LIBTHAL_DYN) $(LIBOLIGOTM_DYN)
RANLIB          = ranlib

PRIMER_OBJECTS1=p3_primer3_boulder_main.o\
                p3_format_output.o\
                p3_read_boulder.o\
                p3_print_boulder.o 

PRIMER_OBJECTS=$(PRIMER_OBJECTS1) $(LIBRARIES)
PRIMER_DYN_OBJECTS=$(PRIMER_OBJECTS1) $(DYNLIBS)
# These are files generated by running ./primer3_core < ../example
example_files=example.for example.rev example.int

#PRIMER3 END

PRIMEGENS_EXE		= ../bin/primegens.exe

    
PRIMEGENS_OBJECTS	= main.o \
			  util.o \
			  sspd.o \
			  fspd.o \
			  pspd.o \
			  probe.o \
			  input.o \
			  pd.o \
			  uhit.o \
			  pphit.o \
			  hbdzn.o \
			  SeqMapping.o \
			  oligotm.o \
			  output.o


EXES 			= $(PRIMEGENS_EXE) $(PRIMER_EXE) $(NTDPAL_EXE) \
			  $(NTTHAL_EXE) $(OLIGOTM_EXE) $(LONG_SEQ_EXE)


all: $(EXES) $(LIBRARIES)

clean_src: 
ifeq ($(TESTOPTS),--windows)
	del /Q /F *.o $(EXES) *~ $(LIBRARIES) $(example_files) core ..\*~
else
	-rm -f *.o $(EXES) *~ $(LIBRARIES) $(DYNLIBS) $(example_files) core ../*~
endif

clean: clean_src

$(PRIMEGENS_EXE): $(PRIMEGENS_OBJECTS)
	$(CC) $(CC_FLAGS) -o $@ $(PRIMEGENS_OBJECTS)

main.o: main.c lib.h defs.h util.h sspd.h fspd.h pspd.h probe.h input.h
	$(CC) -c $(CC_FLAGS) -o $@ main.c

util.o: util.c util.h lib.h defs.h oligotm.h
	$(CC) -c $(CC_FLAGS) -o $@ util.c

sspd.o: sspd.c sspd.h lib.h defs.h hbdzn.h util.h input.h output.h pd.h pphit.h uhit.h
	$(CC) -c $(CC_FLAGS) -o $@ sspd.c

fspd.o: fspd.c fspd.h lib.h defs.h hbdzn.h util.h input.h output.h pd.h pphit.h uhit.h
	$(CC) -c $(CC_FLAGS) -o $@ fspd.c

pspd.o: pspd.c pspd.h lib.h defs.h hbdzn.h util.h input.h output.h pd.h pphit.h uhit.h SeqMapping.h
	$(CC) -c $(CC_FLAGS) -o $@ pspd.c

probe.o: probe.c probe.h lib.h defs.h util.h input.h uhit.h
	$(CC) -c $(CC_FLAGS) -o $@ probe.c

input.o: input.c input.h lib.h defs.h util.h
	$(CC) -c $(CC_FLAGS) -o $@ input.c

pd.o: pd.c pd.h lib.h defs.h util.h
	$(CC) -c $(CC_FLAGS) -o $@ pd.c

uhit.o: uhit.c uhit.h lib.h defs.h util.h
	$(CC) -c $(CC_FLAGS) -o $@ uhit.c

pphit.o: pphit.c pphit.h lib.h defs.h util.h
	$(CC) -c $(CC_FLAGS) -o $@ pphit.c

hbdzn.o: hbdzn.c hbdzn.h lib.h defs.h oligotm.h
	$(CC) -c $(CC_FLAGS) -o $@ hbdzn.c

SeqMapping.o: SeqMapping.c SeqMapping.h lib.h defs.h
	$(CC) -c $(CC_FLAGS) -o $@ SeqMapping.c

oligotm.o: oligotm.c oligotm.h lib.h defs.h
	$(CC) -c $(CC_FLAGS) -o $@ oligotm.c

output.o: output.c output.h lib.h defs.h util.h
	$(CC) -c $(CC_FLAGS) -o $@ output.c

#PRIMER3 Start
$(LIBOLIGOTM): p3_oligotm.o
	$(AR) rv $@ p3_oligotm.o
	$(RANLIB) $@

$(LIBOLIGOTM_LIB): p3_oligotm.o
	$(CC) -shared -W1,-soname,p3_liboligotm.so.1 -o $(LIBOLIGOTM_DYN) p3_oligotm.o

$(LIBDPAL): p3_dpal_primer.o
	$(AR) rv $@ p3_dpal_primer.o
	$(RANLIB) $@

$(LIBDPAL_DYN): p3_dpal_primer.o
	$(CC) -shared -W1,-soname,p3_libdpal.so.1 -o $(LIBDPAL_DYN_LIB) p3_dpal_primer.o

$(LIBTHAL): p3_thal_primer.o
	$(AR) rv $@ p3_thal_primer.o
	$(RANLIB) $@

$(LIBTHAL_DYN): p3_thal_primer.o
	$(CC) -shared -W1,-soname,p3_libthal.so.1 -o $(LIBTHAL_DYN_LIB) p3_thal_primer.o

$(LIBPRIMER3): p3_libprimer3.o p3_seq_lib.o
	$(AR) rv $@ p3_libprimer3.o p3_seq_lib.o
	$(RANLIB) $@

$(LIBPRIMER3_DYN): p3_libprimer3.o p3_seq_lib.o
	$(CC) -shared -W1,-soname,p3_liprimer3.so.1 -o $(LIBPRIMER3_DYN) p3_libprimer3.o p3_seq_lib.o

$(PRIMER_EXE): $(PRIMER_OBJECTS)
	$(CPP) $(LDFLAGS) -o $@ $(PRIMER_OBJECTS) $(LIBOPTS) $(LDLIBS)

p3_libprimer3.o: p3_libprimer3.c p3_libprimer3.h p3_seq_lib.h p3_dpal.h p3_thal.h p3_oligotm.h
	$(CPP) -c $(CFLAGS) -Wno-deprecated $(P_DEFINES) -o $@ p3_libprimer3.c

$(NTDPAL_EXE): p3_ntdpal_main.o p3_dpal.o
	$(CPP) $(LDFLAGS) -o $@ p3_ntdpal_main.o p3_dpal.o

$(NTTHAL_EXE): p3_thal_main.o p3_thal.o
	$(CPP) $(LDFLAGS) -o $@ p3_thal_main.o p3_thal.o $(LDLIBS)

$(OLIGOTM_EXE): p3_oligotm_main.c p3_oligotm.h $(LIBOLIGOTM)
	$(CPP) $(CFLAGS) -o $@ p3_oligotm_main.c $(LIBOLIGOTM) $(LIBOPTS) $(LDLIBS)

$(LONG_SEQ_EXE): p3_long_seq_tm_test_main.c p3_oligotm.o
	$(CPP) $(CFLAGS) -o $@ p3_long_seq_tm_test_main.c p3_oligotm.o $(LIBOPTS) $(LDLIBS)

p3_read_boulder.o: p3_read_boulder.c p3_read_boulder.h p3_libprimer3.h p3_dpal.h p3_thal.h p3_seq_lib.h 
	$(CPP) -c $(CFLAGS) $(P_DEFINES) -o $@ p3_read_boulder.c

p3_print_boulder.o: p3_print_boulder.c p3_print_boulder.h p3_libprimer3.h p3_seq_lib.h 
	$(CPP) -c $(CFLAGS) $(P_DEFINES) -o $@ p3_print_boulder.c

p3_dpal.o: p3_dpal.c p3_dpal.h
	$(CPP) -c $(CFLAGS) -o $@ p3_dpal.c

# We use '-ffloat-store' on windows to prevent undesirable
# precision which may lead to differences in floating point results.
p3_thal.o: p3_thal.c p3_thal.h
	$(CPP) -c $(CFLAGS) -ffloat-store -o $@ p3_thal.c

p3_seq_lib.o: p3_seq_lib.c p3_seq_lib.h p3_libprimer3.h
	$(CPP) -c $(CFLAGS) -o $@ p3_seq_lib.c

p3_dpal_primer.o: p3_dpal.c p3_dpal.h
	$(CPP) -c $(CFLAGS) $(P_DEFINES) -o $@ p3_dpal.c

p3_thal_primer.o: p3_thal.c p3_thal.h
	$(CPP) -c $(CFLAGS) -ffloat-store $(P_DEFINES) -o $@ p3_thal.c

p3_format_output.o: p3_format_output.c p3_format_output.h p3_libprimer3.h p3_dpal.h p3_thal.h p3_seq_lib.h 
	$(CPP) -c $(CFLAGS) $(P_DEFINES) -o $@ p3_format_output.c

p3_ntdpal_main.o: p3_ntdpal_main.c p3_dpal.h
	$(CPP) -c $(CC_OPTS) -o $@ p3_ntdpal_main.c

p3_thal_main.o: p3_thal_main.c p3_thal.h
	$(CPP) -c $(CFLAGS) -o $@ p3_thal_main.c
# We use CC_OPTS above rather than CFLAGS because
# gcc 2.7.2 crashes while compiling ntdpal_main.c with -O2

p3_oligotm.o: p3_oligotm.c p3_oligotm.h

p3_primer3_boulder_main.o: p3_primer3_boulder_main.c p3_libprimer3.h p3_dpal.h p3_thal.h p3_oligotm.h p3_format_output.h p3_print_boulder.h p3_read_boulder.h
	$(CPP) -c $(CFLAGS) $(P_DEFINES) p3_primer3_boulder_main.c

primer_test: test

test: $(PRIMER_EXE) $(NTDPAL_EXE) $(NTTHAL_EXE)

# ======================================================================
# 
# VALGRIND INSTRUCTIONS.
# 
# These instructions work for linux, and run the 'memcheck'
# functionality of valgrind.  Tests will be _much_ slower
# when running with valgrind checks.
# 
# If necessary, get and install valgrind (should come with most
# Linux's, but you need valgrind >= 3.2.3)
# 
# In the src directory for primer3:
#  
# $ make clean
# 
# Re-complile without optimization and run the normal tests, does
# _not_ valgrind them:
#
# $ make O_OPTS=-O0 test  # The value of O_OPTS is Minus Oh Zero 
# 
# Run valgrind on a small example:
#
# $ valgrind --leak-check=yes --show-reachable=yes --log-file-exactly=p3vg ./primer3_core < ../example
#
# Check output in file p3vg 
#
# Note: Valgrind is at /usr/local/bin/valgrind at WI
# 
# OK, now for the real tests:
#
# $ cd ../test
# 
# Check valgrind path in p3test.pl, ntdpal_test.pl, and oligotm_test.pl
# and correct if necessary.  This code works under valgrind 3.2.3.
# 
# $ make TESTOPTS=--valgrind  # Remember, you have to be in test/
# 
# When the --valgrind flag is set, the perl test scripts grep for and
# display errors and leaks, but you need to ***look at the output** to
# see these and figure out which test caused the problem, so you can
# debug it.
#
# ======================================================================
   

#PRIMER3 END
